var global = this

global.methodFunc = function(instance, clsName, methodName, args, isSuper, isPerformSelector) {
  var selectorName = methodName
  if (!isPerformSelector) {
    methodName = methodName.replace(/__/g, "-")
    selectorName = methodName.replace(/_/g, ":").replace(/-/g, "_")
    var marchArr = selectorName.match(/:/g)
    var numOfArgs = marchArr ? marchArr.length : 0
    if (args.length > numOfArgs) {
      selectorName += ":"
    }
  }
  var ret = instance ? _nature_callI(instance, selectorName, args, isSuper):
                       _nature_callC(clsName, selectorName, args)
  return ret
}





global.customMethods = {
    __fn: function(methodName) {
        var slf = this
//        if (slf.__obj == undefined){
//            slf.__obj = this;
//        }
        if (!slf.__clsName){
            slf.__obj = this;
        }
      return function(){
        var args = Array.prototype.slice.call(arguments);
        //var ret = global.methodFunc(slf.__obj, slf.__clsName, methodName, args, slf.__isSuper);
        var ret = global.methodFunc(slf.__obj, slf.__clsName, methodName, args, slf.__isSuper);
        return ret;
      }
    },
}


global.require = function(clsName) {
  if (!global[clsName]) {
    global[clsName] = {
      __clsName: clsName
    }
  }
  return global[clsName]
}

global.orgFunc = function(orgFunc,args) {
    return _nature_orgFunc(orgFunc,args)
}
global.jsCall = function(declaration,instance,naturalOrgFunc,args) {

    beforeSelf = global.self;
    var className = declaration.substring(0,declaration.indexOf("_"));
    instance.__obj = instance;
    instance.__clsName = className;
    instance.__naturalOrgFunc = naturalOrgFunc;
    var ret = global[declaration](...args);
    global.self = instance;
    return ret
}

global.defineClass = function(declaration, instMethods, clsMethods) {
    
    for (var key in instMethods) {
        instMethod = instMethods[key]
        name = declaration + '_' + key ;
        global[name] = instMethod
        _nature_defineClass('jsCall',name,instMethods,null,instMethod.length)
    }
    for (var key in clsMethods){
        instMethod = clsMethods[key]
        name = declaration + '_' + key ;
        global[name] = instMethod
        _nature_defineClass('jsCall',name,null,clsMethods,instMethod.length)
    }
    for (var method in global.customMethods){
        var a = Object.defineProperty(Object.prototype, method, {value: global.customMethods[method], configurable:false, enumerable: false})
    }
    
    return require(declaration)
}





